🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / androidApp / src / google / kotlin / org / meshtastic / app / map / offline / pmtiles / MvtDecoder.kt
Displaying Raw • Download
androidApp/src/google/kotlin/org/meshtastic/app/map/offline/pmtiles/MvtDecoder.kt renovate/fastlane-2.x-lockfile (056eed64) Text, 5.14 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.app.map.offline.pmtiles
T8b949e/** A point in a feature's own tile-local coordinate space, `0 until layer.extent` on each axis. */
Tff7b72internal Tff7b72data Tff7b72class T56d364TileCoordTb4b4b4(Tff7b72val Te6edf3xTb4b4b4: Tffa657IntTb4b4b4, Tff7b72val Te6edf3yTb4b4b4: Tffa657IntTb4b4b4)
T8b949e/**
* Decodes an MVT feature's `geometry` command stream (spec section 4.3) into tile-local point rings.
*
* For [org.meshtastic.app.map.offline.pmtiles.VectorTile.GEOM_POINT] the single returned ring is every point of a
* Point/MultiPoint feature. For `GEOM_LINESTRING` each ring is one polyline. For `GEOM_POLYGON` each ring is one closed
* ring (exterior or a hole; MVT gives no explicit hole flag — winding order is what distinguishes them, and this
* decoder doesn't need to tell them apart since [OfflineVectorOverlay] draws every ring it's given as its own
* independent [com.google.maps.android.compose.Polygon] — no hole grouping, see that file's doc comment).
*/
Tff7b72internal Tff7b72object T56d364MvtDecoder Tb4b4b4{
Tff7b72private Tff7b72const Tff7b72val Te6edf3COMMAND_MOVE_TO Tff7b72= T79c0ff1
Tff7b72private Tff7b72const Tff7b72val Te6edf3COMMAND_LINE_TO Tff7b72= T79c0ff2
Tff7b72private Tff7b72const Tff7b72val Te6edf3COMMAND_CLOSE_PATH Tff7b72= T79c0ff7
Tff7b72private Tff7b72const Tff7b72val Te6edf3COMMAND_ID_BITS Tff7b72= T79c0ff3
Tff7b72private Tff7b72const Tff7b72val Te6edf3COMMAND_ID_MASK Tff7b72= T79c0ff0Te6edf3x7
Tff7b72fun Td2a8ffdecodeGeometryTb4b4b4(Te6edf3typeTb4b4b4: Tffa657IntTb4b4b4, Te6edf3commandsTb4b4b4: Te6edf3ListTff7b72<Tffa657IntTff7b72>Tb4b4b4)Tb4b4b4: Te6edf3ListTff7b72<Te6edf3ListTff7b72<Te6edf3TileCoordTff7b72>Tff7b72> Tff7b72= Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3VectorTileTb4b4b4.Te6edf3GEOM_POINTTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3points Tff7b72=
Te6edf3collectDeltaStepsTb4b4b4(Te6edf3commandsTb4b4b4)
Tb4b4b4.Te6edf3runningFoldTb4b4b4(Te6edf3TileCoordTb4b4b4(T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3cursorTb4b4b4, Te6edf3step Tff7b72-Tff7b72> Te6edf3TileCoordTb4b4b4(Te6edf3cursorTb4b4b4.Te6edf3x Tff7b72+ Te6edf3stepTb4b4b4.Te6edf3dxTb4b4b4, Te6edf3cursorTb4b4b4.Te6edf3y Tff7b72+ Te6edf3stepTb4b4b4.Te6edf3dyTb4b4b4) Tb4b4b4}
Tb4b4b4.Te6edf3dropTb4b4b4(T79c0ff1Tb4b4b4) T8b949e// the runningFold seed, not a decoded point
Tff7b72if Tb4b4b4(Te6edf3pointsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Te6edf3emptyListTb4b4b4(Tb4b4b4) Tff7b72else Te6edf3listOfTb4b4b4(Te6edf3pointsTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3decodeRingsTb4b4b4(Te6edf3commandsTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffdecodeRingsTb4b4b4(Te6edf3commandsTb4b4b4: Te6edf3ListTff7b72<Tffa657IntTff7b72>Tb4b4b4)Tb4b4b4: Te6edf3ListTff7b72<Te6edf3ListTff7b72<Te6edf3TileCoordTff7b72>Tff7b72> Tb4b4b4{
Tff7b72val Te6edf3rings Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3MutableListTff7b72<Te6edf3TileCoordTff7b72>Tff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3cursor Tff7b72= Te6edf3TileCoordTb4b4b4(T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4)
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffdetekt:DoubleMutabilityForCollectionTa5d6ff"Tb4b4b4)
Tff7b72var Te6edf3currentTb4b4b4: Te6edf3MutableListTff7b72<Te6edf3TileCoordTff7b72>Tff7b72? Tff7b72= Tff7b72null
Tff7b72for Tb4b4b4(Te6edf3step Tff7b72in Te6edf3collectDeltaStepsTb4b4b4(Te6edf3commandsTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72when Tb4b4b4(Te6edf3stepTb4b4b4.Te6edf3commandTb4b4b4) Tb4b4b4{
Te6edf3COMMAND_MOVE_TO Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3cursor Tff7b72= Te6edf3TileCoordTb4b4b4(Te6edf3cursorTb4b4b4.Te6edf3x Tff7b72+ Te6edf3stepTb4b4b4.Te6edf3dxTb4b4b4, Te6edf3cursorTb4b4b4.Te6edf3y Tff7b72+ Te6edf3stepTb4b4b4.Te6edf3dyTb4b4b4)
Te6edf3current Tff7b72= Te6edf3mutableListOfTb4b4b4(Te6edf3cursorTb4b4b4)Tb4b4b4.Te6edf3also Tb4b4b4{ Te6edf3rings Tff7b72+Tff7b72= Tffa657it Tb4b4b4}
Tb4b4b4}
Te6edf3COMMAND_LINE_TO Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3cursor Tff7b72= Te6edf3TileCoordTb4b4b4(Te6edf3cursorTb4b4b4.Te6edf3x Tff7b72+ Te6edf3stepTb4b4b4.Te6edf3dxTb4b4b4, Te6edf3cursorTb4b4b4.Te6edf3y Tff7b72+ Te6edf3stepTb4b4b4.Te6edf3dyTb4b4b4)
Te6edf3currentTff7b72?.Te6edf3addTb4b4b4(Te6edf3cursorTb4b4b4)
Tb4b4b4}
Te6edf3COMMAND_CLOSE_PATH Tff7b72-Tff7b72>
T8b949e// ClosePath draws an implicit edge back to the ring's start; materialize it so every ring this
T8b949e// decoder returns is already a closed polygon, whether or not the caller re-closes it itself.
Te6edf3currentTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3ring Tff7b72-Tff7b72> Tff7b72if Tb4b4b4(Te6edf3ringTb4b4b4.Te6edf3size Tff7b72> T79c0ff1Tb4b4b4) Te6edf3ringTb4b4b4.Te6edf3addTb4b4b4(Te6edf3ringTb4b4b4.Te6edf3firstTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3rings
Tb4b4b4}
T8b949e/** One MoveTo/LineTo parameter pair, already zigzag-decoded; ClosePath carries no delta (dx = dy = 0). */
Tff7b72private Tff7b72data Tff7b72class T56d364DeltaStepTb4b4b4(Tff7b72val Te6edf3commandTb4b4b4: Tffa657IntTb4b4b4, Tff7b72val Te6edf3dxTb4b4b4: Tffa657IntTb4b4b4, Tff7b72val Te6edf3dyTb4b4b4: Tffa657IntTb4b4b4)
T8b949e/** Expands the packed `(id | count<<3), [zigzag dx, zigzag dy] * count` stream into one entry per delta. */
Tff7b72private Tff7b72fun Td2a8ffcollectDeltaStepsTb4b4b4(Te6edf3commandsTb4b4b4: Te6edf3ListTff7b72<Tffa657IntTff7b72>Tb4b4b4)Tb4b4b4: Te6edf3ListTff7b72<Te6edf3DeltaStepTff7b72> Tb4b4b4{
Tff7b72val Te6edf3steps Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3DeltaStepTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3i Tff7b72= T79c0ff0
T8b949e// Labeled so a truncated stream can abandon parsing entirely: `count` comes straight off the wire (up to
T8b949e// ~536M), and `repeat(count) { return@repeat }` would only skip one iteration per truncated element.
Tf0883eouter@ Tff7b72while Tb4b4b4(Te6edf3i Tff7b72< Te6edf3commandsTb4b4b4.Te6edf3sizeTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3commandInteger Tff7b72= Te6edf3commandsTff7b72[Te6edf3iTff7b72]
Te6edf3iTff7b72+Tff7b72+
Tff7b72val Te6edf3id Tff7b72= Te6edf3commandInteger Te6edf3and Te6edf3COMMAND_ID_MASK
Tff7b72val Te6edf3count Tff7b72= Te6edf3commandInteger Te6edf3ushr Te6edf3COMMAND_ID_BITS
Tff7b72if Tb4b4b4(Te6edf3id Tff7b72=Tff7b72= Te6edf3COMMAND_CLOSE_PATHTb4b4b4) Tb4b4b4{
T8b949e// count is always 1 for ClosePath from every real encoder, but the spec allows more; honor it.
Te6edf3repeatTb4b4b4(Te6edf3countTb4b4b4) Tb4b4b4{ Te6edf3steps Tff7b72+Tff7b72= Te6edf3DeltaStepTb4b4b4(Te6edf3idTb4b4b4, Te6edf3dx Tff7b72= T79c0ff0Tb4b4b4, Te6edf3dy Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4}
Tff7b72continue
Tb4b4b4}
Tff7b72var Te6edf3remaining Tff7b72= Te6edf3count
Tff7b72while Tb4b4b4(Te6edf3remaining Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72+ T79c0ff1 Tff7b72>Tff7b72= Te6edf3commandsTb4b4b4.Te6edf3sizeTb4b4b4) Tff7b72breakTf0883e@outer T8b949e// Truncated stream from a malformed tile; drop the rest.
Tff7b72val Te6edf3dx Tff7b72= Te6edf3zigZagDecodeTb4b4b4(Te6edf3commandsTff7b72[Te6edf3iTff7b72]Tb4b4b4)
Tff7b72val Te6edf3dy Tff7b72= Te6edf3zigZagDecodeTb4b4b4(Te6edf3commandsTff7b72[Te6edf3i Tff7b72+ T79c0ff1Tff7b72]Tb4b4b4)
Te6edf3i Tff7b72+Tff7b72= T79c0ff2
Te6edf3steps Tff7b72+Tff7b72= Te6edf3DeltaStepTb4b4b4(Te6edf3idTb4b4b4, Te6edf3dxTb4b4b4, Te6edf3dyTb4b4b4)
Te6edf3remainingTff7b72-Tff7b72-
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3steps
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffzigZagDecodeTb4b4b4(Te6edf3valueTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Tffa657Int Tff7b72= Tb4b4b4(Te6edf3value Te6edf3ushr T79c0ff1Tb4b4b4) Te6edf3xor Tff7b72-Tb4b4b4(Te6edf3value Te6edf3and T79c0ff1Tb4b4b4)
Tb4b4b4}
Served by rngit 1.5.2 - Generated in 0.07s